package com.gs.netty.server.auth;

import com.gs.netty.core.common.NettyConstants;
import com.gs.netty.server.NettyServerConfig;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

import static io.netty.handler.codec.http.HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

@Component
@ChannelHandler.Sharable
public class WebSocketAuthHandler extends ChannelDuplexHandler {

    @Autowired
    private NettyServerConfig nettyServerConfig;

    public WebSocketAuthHandler(NettyServerConfig nettyServerConfig) {
        this.nettyServerConfig = nettyServerConfig;
    }

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        if (msg instanceof FullHttpResponse) {
            FullHttpResponse httpMsg = (FullHttpResponse) msg;
            httpMsg.headers().set(NettyConstants.SERVICE_WEIGHT, nettyServerConfig.getWeight());
            ctx.write(msg, promise).addListener(future -> {
                if (future.isSuccess()) {
                    ctx.pipeline().remove(NettyConstants.AUTH_HANDLER);
                }
            });
        } else {
            super.write(ctx, msg, promise);
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof FullHttpRequest) {
            FullHttpRequest request = (FullHttpRequest) msg;

            if (nettyServerConfig.getWebSocketPath().equalsIgnoreCase(request.uri()) &&  isValidWebSocketRequest(request)) {
                // ❌ 认证失败，返回错误响应
                sendUnauthorizedResponse(ctx, "Token 错误或缺失");
                request.release(); // 释放资源
            } else {
                // ✅ 校验通过，放行
                super.channelRead(ctx, msg);
            }
        } else {
            super.channelRead(ctx, msg);
        }
    }

    private boolean isValidWebSocketRequest(FullHttpRequest request) {
        HttpHeaders headers = request.headers();
        String token = headers.get("Authorization");
        if (StringUtils.isNotEmpty(token) ) {

            return false;
        }else {


            // ✅ 获取 token（从 header 或 URL 参数）
            String protocolsStr = headers.get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL);
            String[] protocols = null;

            if (StringUtils.isEmpty(protocolsStr) || (
                    (protocols = StringUtils.split(protocolsStr, ',')).length != 2)
            ) {
                // 认证错误
                return true;
            }
            token = protocols[1];
            //TODO  校验逻辑：你可以在这里接入 Redis、JWT 校验、数据库查询等
            return false;
        }
    }

    private void sendUnauthorizedResponse(ChannelHandlerContext ctx, String message) {
        byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
        ByteBuf content = Unpooled.wrappedBuffer(bytes);

        FullHttpResponse response = new DefaultFullHttpResponse(
                HTTP_1_1,
                HttpResponseStatus.UNAUTHORIZED,
                content
        );

        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, bytes.length);
        response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);

        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
}
